package org.huatek.anders.body;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.huatek.anders.constants.RedisKeys;
import org.huatek.anders.exception.ApiException;
import org.huatek.anders.utils.RedisUtils;
import org.huatek.anders.utils.jwt.JwtSubject;
import org.huatek.anders.utils.jwt.JwtToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

/**
 * @author anders
 * @date 2018-12-20 15:12
 **/
@Slf4j
@RestControllerAdvice
public class TokenResponseBodyAdvice implements ResponseBodyAdvice<Map<String, Object>> {


    private final RedisUtils redisUtils;
    @Autowired
    public TokenResponseBodyAdvice(RedisUtils redisUtils){
        this.redisUtils = redisUtils;
    }
    @Value("${common.log.show}")
    private boolean logShow;
    @Value("${common.visitor.url}")
    private String[] visitorUrl;
    @Value("${common.token.name}")
    private String tokenName;
    @Value("${common.token.time}")
    private int tokenTime;

    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    @Override
    public Map<String, Object> beforeBodyWrite(Map<String, Object> body, MethodParameter returnType, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        ServletServerHttpRequest sshr=(ServletServerHttpRequest) serverHttpRequest;
        HttpServletRequest request = sshr.getServletRequest();
        String visitUrl = request.getRequestURL().toString();
        if(Arrays.stream(visitorUrl).anyMatch(url -> visitUrl.indexOf(url)>0)){
            return body;
        }else{
            String token = JwtToken.getToken(request, tokenName);
            ObjectMapper mapper = new ObjectMapper();
            try {
                JwtSubject jwtSubject = mapper.readValue(JwtToken.getSubject(token), JwtSubject.class);
                String newToken = JwtToken.buildJWT(JwtToken.generalSubject(jwtSubject), tokenTime);
                /// redisUtils.set(RedisKeys.OAUTH2_USER_TOKEN + jwtSubject.getUserId(), newToken, tokenTime);
                body.put("token", newToken);
                if (logShow){
                    log.debug("==============打印返回参数begin=============");
                    log.debug(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(body));
                    log.debug("==============打印返回参数end=============");
                }
            } catch (IOException e) {
                throw new ApiException("Response 生成token异常");
            }
        }

        return body;
    }
}
